package cn.school.publicPhone.service.impl;

import cn.school.common.utils.SysUserUtils;
import cn.school.publicPhone.dao.FaceInfoDao;
import cn.school.publicPhone.entity.PhoneFaceSync;
import cn.school.publicPhone.service.FaceInfoServer;
import cn.school.publicPhone.service.PhoneLoginService;
import cn.school.publicPhone.vo.PhoneFaceSyncVO;
import cn.school.student.entity.StudentInfo;
import cn.school.student.service.StudentInfoService;
import cn.school.telephone.bean.addmodify.ReqEntity;
import cn.school.telephone.bean.addmodify.TelephoneReq;
import cn.school.telephone.bean.addmodify.TelephoneReqDto;
import cn.school.telephone.bean.addmodify.TelephoneResponse;
import cn.school.telephone.bean.get.SyncUserInfoEntity;
import cn.school.telephone.service.TelephoneService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class FaceInfoServerImpl extends ServiceImpl<FaceInfoDao, PhoneFaceSync> implements FaceInfoServer {

    @Resource
    FaceInfoDao faceInfoDao;
    @Resource
    PhoneLoginService phoneLoginService;

    @Value("${student.picturePathDir}")
    private String imagePath;

    @Autowired
    private TelephoneService telephoneService;

    @Autowired
    private StudentInfoService studentInfoService;


    @Override
    public IPage<PhoneFaceSyncVO> getFaceList(PhoneFaceSyncVO vo) {
        vo.setTenantId(SysUserUtils.getSysUser().getTenantId());
        int count = faceInfoDao.getFaceSyncCount(vo);
        int startNum = (vo.getPageNum() - 1) * vo.getPageSize();
        vo.setPageNum(startNum);
        List<PhoneFaceSyncVO> examInfoList = faceInfoDao.getFaceSyncList(vo);
        IPage<PhoneFaceSyncVO> page = new Page<>();
        page.setTotal(count);
        page.setRecords(examInfoList);
        return page;
    }

    @Override
    public String operationFaceSync(PhoneFaceSyncVO vo) {
        String result = publicOperationFaceSync(vo);
        if (result.isEmpty()) {
            // 公告电话人脸同步
            int num = addSyncBatch(Collections.singletonList(vo.getId()));
            result = num > 0 ? "" : "error";
        }
        return result;
    }

    public String publicOperationFaceSync(PhoneFaceSyncVO vo) {
        Map<String, String> map = new HashMap<>();
        map.put("group_id", "SHPIP");
        map.put("image_type", "BASE64");
        map.put("user_id", vo.getId() + "");
        String file = imagePath + vo.getStudentPicture();
        String base64Image = encodeImage(file);
        map.put("image", base64Image);
//        String result = phoneLoginService.faceRegisterToBaidu(map);
        String result = null;
        if (StringUtils.isEmpty(result)) {
            //添加人脸同步信息
            PhoneFaceSync entity = new PhoneFaceSync();
            BeanUtils.copyProperties(vo, entity);
            entity.setSyncStatus("1");
            entity.setStudentId(vo.getId() + "");

            entity.setPhoneStudentId(vo.getId() + "");
            entity.setPhoneStudentName(vo.getStudentName());

            int num = faceInfoDao.insert(entity);
            return num > 0 ? "" : "error";
        } else {
            return result;
        }
    }

    // 接收学生id集合批量同步照片到话机
    private int addSyncBatch(List<Long> ids) {
        List<TelephoneReq> telephoneReqs = new ArrayList<>();
        for (Long id : ids) {
            StudentInfo studentInfo = studentInfoService.getById(id);
            String picture = studentInfo.getStudentPicture();
            String url = "https://www.zhxypt.net/api/student/picture/" + picture.substring
                    (0, picture.lastIndexOf("/") + 1) + URLEncoder.encode(picture.substring(picture.lastIndexOf("/") + 1));
            telephoneReqs.add(
                    new TelephoneReq(
                            studentInfo.getName(), url, String.valueOf(id), "", "1"));
        }
        TelephoneReqDto telephoneReqDto = new TelephoneReqDto(new ReqEntity(null, telephoneReqs));
        TelephoneResponse telephoneResponse = telephoneService.syncBatchUserFaceImageByUrl(telephoneReqDto);
        if (telephoneResponse == null || !"200".equals(telephoneResponse.getCode())) {
            System.err.println("学生照片同步到话机失败");
            return 0;
        }
        return telephoneResponse.getResEntity().getSuccessNum();
    }


    private String encodeImage(String imagePath) {
        File file = new File(imagePath);
        try (FileInputStream imageInFile = new FileInputStream(file)) {
            // 读取图片文件并转换为字节数组
            byte[] imageData = new byte[(int) file.length()];
            imageInFile.read(imageData);

            // 将字节数组转换为Base64编码
            return Base64.getEncoder().encodeToString(imageData);
        } catch (IOException e) {
            System.out.println("Error reading image file: " + e.getMessage());
            return null;
        }
    }

    @Override
    public String deleteFaceInfo(PhoneFaceSyncVO vo) {
        String result = publicDeleteFaceInfo(vo);
        if (result.isEmpty()) {
            // 公告电话人脸删除
            Long studentId = vo.getId();
            Map<String, Object> resultMap = telephoneService.syncDelSomeUserByAllUser(null,
                    Collections.singletonList(String.valueOf(studentId)));

            if (!String.valueOf(resultMap.get("code")).equals("200")) {
                result = "error";
            }
        }
        return result;
    }

    private String publicDeleteFaceInfo(PhoneFaceSyncVO vo) {
        Map<String, String> map = new HashMap<>();
        map.put("group_id", "SHPIP");
        map.put("user_id", vo.getId() + "");
//        String result = phoneLoginService.deleteFaceRegisterToBaidu(map);
        String result = null;
        if (StringUtils.isEmpty(result)) {
            //删除人脸同步信息
            LambdaQueryWrapper<PhoneFaceSync> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(PhoneFaceSync::getStudentId, vo.getId());
            int num = faceInfoDao.delete(wrapper);

            return num > 0 ? "" : "error";
        } else {
            return result;
        }
    }

    @Override
    public String batchCurdFaceSync(List<PhoneFaceSyncVO> vos, String type) {
        String result = "";
        if ("0".equals(type)) {
            for (PhoneFaceSyncVO vo : vos) {
                result = publicOperationFaceSync(vo);
            }
            if (result.isEmpty()) {
                // 同步话机人脸
                List<Long> ids = vos.stream().map(PhoneFaceSyncVO::getId).collect(Collectors.toList());
                int num = addSyncBatch(ids);
                result = num == ids.size() ? "" : "error";
            }

        } else if ("1".equals(type)) {
            for (PhoneFaceSyncVO vo : vos) {
                result = publicUpdateFaceSync(vo);
            }
            if (result.isEmpty()) {
                // 修改话机人脸
                List<Long> ids = vos.stream().map(PhoneFaceSyncVO::getId).collect(Collectors.toList());
                int num = addSyncBatch(ids);
                return num == ids.size() ? "" : "error";
            }

        } else if ("2".equals(type)) {
            List<String> studentIds = new ArrayList<>();
            for (PhoneFaceSyncVO vo : vos) {
                result = publicDeleteFaceInfo(vo);
                studentIds.add(String.valueOf(vo.getId()));
            }
            if (result.isEmpty()) {
                // 删除话机人脸
                Map<String, Object> resultMap = telephoneService.syncDelSomeUserByAllUser(null, studentIds);
                if (!String.valueOf(resultMap.get("code")).equals("200")) {
                    result = "error";
                }
            }
        }
        return result;
    }

    @Override
    public String syncPhoneStudentsToFaceInfoServer() {
        // 获取话机那边的所有用户信息保存到t_phone_face_sync表
        List<SyncUserInfoEntity> phoneStudent = telephoneService.getPhoneStudent();

        LambdaQueryWrapper<PhoneFaceSync> pfsLqw = new LambdaQueryWrapper<>();
        pfsLqw.eq(PhoneFaceSync::getTenantId, SysUserUtils.getSysUser().getTenantId());
        List<String> phoneStudentIds = faceInfoDao.selectList(pfsLqw).stream()
                .map(PhoneFaceSync::getPhoneStudentId).collect(Collectors.toList());

        LambdaQueryWrapper<StudentInfo> siLqw = new LambdaQueryWrapper<>();
        siLqw.eq(StudentInfo::getTenantId, SysUserUtils.getSysUser().getTenantId());
        Map<Long, StudentInfo> longStudentInfoMap = studentInfoService.list(siLqw).stream()
                .collect(Collectors.toMap(StudentInfo::getId, Function.identity()));

        List<PhoneFaceSync> toInsert = new ArrayList<>();
        for (SyncUserInfoEntity syncUserInfoEntity : phoneStudent) {
            LambdaQueryWrapper<PhoneFaceSync> lqw = new LambdaQueryWrapper<>();
            lqw.eq(PhoneFaceSync::getPhoneStudentId, syncUserInfoEntity.getCardNumber());
            if (phoneStudentIds.contains(syncUserInfoEntity.getCardNumber())) {
                // 存在，更新
                PhoneFaceSync entity = new PhoneFaceSync();
                entity.setPhoneStudentName(syncUserInfoEntity.getName());
                faceInfoDao.update(entity, lqw);
            } else {
                // 不存在，插入
                PhoneFaceSync entity = new PhoneFaceSync();
                entity.setPhoneStudentName(syncUserInfoEntity.getName());
                entity.setSyncStatus("0");
                entity.setPhoneStudentId(syncUserInfoEntity.getCardNumber());
                entity.setTenantId(SysUserUtils.getSysUser().getTenantId());
                try {
                    StudentInfo studentInfo = longStudentInfoMap.get(Long.valueOf(syncUserInfoEntity.getCardNumber()));
                    if (studentInfo != null) {
                        entity.setSyncStatus("1");
                        entity.setStudentId(syncUserInfoEntity.getCardNumber());
                        entity.setStudentName(syncUserInfoEntity.getName());
                        if (studentInfo.getClassId() != null) {
                            entity.setClassId(String.valueOf(studentInfo.getClassId()));
                        }
                        entity.setClassName(studentInfo.getClassName());
                    }
                } catch (NumberFormatException e) {
                    System.out.println(e.getMessage());
                }
                // 加入待插入集合
                toInsert.add(entity);
            }
        }
        if (!toInsert.isEmpty()) {
            faceInfoDao.insertAll(toInsert);
        }
        return "";
    }


    @Override
    public String updateFaceSync(PhoneFaceSyncVO vo) {
        String result = publicUpdateFaceSync(vo);
        if (result.isEmpty()) {
            // 更新话机人脸
            int num = addSyncBatch(Collections.singletonList(vo.getId()));
            result = num > 0 ? "" : "error";
        }
        return result;
    }

    public String publicUpdateFaceSync(PhoneFaceSyncVO vo) {
        Map<String, String> map = new HashMap<>();
        map.put("group_id", "SHPIP");
        map.put("image_type", "BASE64");
        map.put("user_id", vo.getId() + "");
        String file = imagePath + vo.getStudentPicture();
        String base64Image = encodeImage(file);
        map.put("image", base64Image);
//        String result = phoneLoginService.updateFaceRegisterToBaidu(map);
        String result = "0";
        if ("0".equals(result)) {
            //添加人脸同步信息
            PhoneFaceSync entity = new PhoneFaceSync();
            entity.setModifyTime(new Date());

            entity.setPhoneStudentId(vo.getPhoneStudentId());
            entity.setPhoneStudentName(vo.getStudentName());

            LambdaQueryWrapper<PhoneFaceSync> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(PhoneFaceSync::getStudentId, vo.getId());
            int num = faceInfoDao.update(entity, wrapper);
            return num > 0 ? "" : "error";
        } else {
            return result;
        }
    }
}
